package com.mycompany.myapp.web.rest;

import com.mycompany.myapp.JhipsterApp;
import com.mycompany.myapp.domain.Commodity;
import com.mycompany.myapp.repository.CommodityRepository;
import com.mycompany.myapp.service.CommodityService;
import com.mycompany.myapp.service.dto.CommodityDTO;
import com.mycompany.myapp.service.mapper.CommodityMapper;
import com.mycompany.myapp.web.rest.errors.ExceptionTranslator;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.Validator;

import javax.persistence.EntityManager;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.ZoneOffset;
import java.time.ZoneId;
import java.util.List;

import static com.mycompany.myapp.web.rest.TestUtil.sameInstant;
import static com.mycompany.myapp.web.rest.TestUtil.createFormattingConversionService;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

/**
 * Integration tests for the {@Link CommodityResource} REST controller.
 */
@SpringBootTest(classes = JhipsterApp.class)
public class CommodityResourceIT {

    private static final String DEFAULT_CNAME = "AAAAAAAAAA";
    private static final String UPDATED_CNAME = "BBBBBBBBBB";

    private static final Integer DEFAULT_STAR = 1;
    private static final Integer UPDATED_STAR = 2;

    private static final Double DEFAULT_PRICE = 1D;
    private static final Double UPDATED_PRICE = 2D;

    private static final String DEFAULT_IMG_URL = "AAAAAAAAAA";
    private static final String UPDATED_IMG_URL = "BBBBBBBBBB";

    private static final String DEFAULT_DETAIL = "AAAAAAAAAA";
    private static final String UPDATED_DETAIL = "BBBBBBBBBB";

    private static final String DEFAULT_MODEL = "AAAAAAAAAA";
    private static final String UPDATED_MODEL = "BBBBBBBBBB";

    private static final ZonedDateTime DEFAULT_CREATE_TIME = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0L), ZoneOffset.UTC);
    private static final ZonedDateTime UPDATED_CREATE_TIME = ZonedDateTime.now(ZoneId.systemDefault()).withNano(0);

    private static final Integer DEFAULT_COUNT = 1;
    private static final Integer UPDATED_COUNT = 2;

    private static final String DEFAULT_FASHION = "AAAAAAAAAA";
    private static final String UPDATED_FASHION = "BBBBBBBBBB";

    private static final String DEFAULT_QUALITY = "AAAAAAAAAA";
    private static final String UPDATED_QUALITY = "BBBBBBBBBB";

    private static final String DEFAULT_BRAND = "AAAAAAAAAA";
    private static final String UPDATED_BRAND = "BBBBBBBBBB";

    @Autowired
    private CommodityRepository commodityRepository;

    @Autowired
    private CommodityMapper commodityMapper;

    @Autowired
    private CommodityService commodityService;

    @Autowired
    private MappingJackson2HttpMessageConverter jacksonMessageConverter;

    @Autowired
    private PageableHandlerMethodArgumentResolver pageableArgumentResolver;

    @Autowired
    private ExceptionTranslator exceptionTranslator;

    @Autowired
    private EntityManager em;

    @Autowired
    private Validator validator;

    private MockMvc restCommodityMockMvc;

    private Commodity commodity;

    @BeforeEach
    public void setup() {
        MockitoAnnotations.initMocks(this);
        final CommodityResource commodityResource = new CommodityResource(commodityService);
        this.restCommodityMockMvc = MockMvcBuilders.standaloneSetup(commodityResource)
            .setCustomArgumentResolvers(pageableArgumentResolver)
            .setControllerAdvice(exceptionTranslator)
            .setConversionService(createFormattingConversionService())
            .setMessageConverters(jacksonMessageConverter)
            .setValidator(validator).build();
    }

    /**
     * Create an entity for this test.
     *
     * This is a static method, as tests for other entities might also need it,
     * if they test an entity which requires the current entity.
     */
    public static Commodity createEntity(EntityManager em) {
        Commodity commodity = new Commodity()
            .cname(DEFAULT_CNAME)
            .star(DEFAULT_STAR)
            .price(DEFAULT_PRICE)
            .imgUrl(DEFAULT_IMG_URL)
            .detail(DEFAULT_DETAIL)
            .model(DEFAULT_MODEL)
            .createTime(DEFAULT_CREATE_TIME)
            .count(DEFAULT_COUNT)
            .fashion(DEFAULT_FASHION)
            .quality(DEFAULT_QUALITY)
            .brand(DEFAULT_BRAND);
        return commodity;
    }
    /**
     * Create an updated entity for this test.
     *
     * This is a static method, as tests for other entities might also need it,
     * if they test an entity which requires the current entity.
     */
    public static Commodity createUpdatedEntity(EntityManager em) {
        Commodity commodity = new Commodity()
            .cname(UPDATED_CNAME)
            .star(UPDATED_STAR)
            .price(UPDATED_PRICE)
            .imgUrl(UPDATED_IMG_URL)
            .detail(UPDATED_DETAIL)
            .model(UPDATED_MODEL)
            .createTime(UPDATED_CREATE_TIME)
            .count(UPDATED_COUNT)
            .fashion(UPDATED_FASHION)
            .quality(UPDATED_QUALITY)
            .brand(UPDATED_BRAND);
        return commodity;
    }

    @BeforeEach
    public void initTest() {
        commodity = createEntity(em);
    }

    @Test
    @Transactional
    public void createCommodity() throws Exception {
        int databaseSizeBeforeCreate = commodityRepository.findAll().size();

        // Create the Commodity
        CommodityDTO commodityDTO = commodityMapper.toDto(commodity);
        restCommodityMockMvc.perform(post("/api/commodities")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(commodityDTO)))
            .andExpect(status().isCreated());

        // Validate the Commodity in the database
        List<Commodity> commodityList = commodityRepository.findAll();
        assertThat(commodityList).hasSize(databaseSizeBeforeCreate + 1);
        Commodity testCommodity = commodityList.get(commodityList.size() - 1);
        assertThat(testCommodity.getCname()).isEqualTo(DEFAULT_CNAME);
        assertThat(testCommodity.getStar()).isEqualTo(DEFAULT_STAR);
        assertThat(testCommodity.getPrice()).isEqualTo(DEFAULT_PRICE);
        assertThat(testCommodity.getImgUrl()).isEqualTo(DEFAULT_IMG_URL);
        assertThat(testCommodity.getDetail()).isEqualTo(DEFAULT_DETAIL);
        assertThat(testCommodity.getModel()).isEqualTo(DEFAULT_MODEL);
        assertThat(testCommodity.getCreateTime()).isEqualTo(DEFAULT_CREATE_TIME);
        assertThat(testCommodity.getCount()).isEqualTo(DEFAULT_COUNT);
        assertThat(testCommodity.getFashion()).isEqualTo(DEFAULT_FASHION);
        assertThat(testCommodity.getQuality()).isEqualTo(DEFAULT_QUALITY);
        assertThat(testCommodity.getBrand()).isEqualTo(DEFAULT_BRAND);
    }

    @Test
    @Transactional
    public void createCommodityWithExistingId() throws Exception {
        int databaseSizeBeforeCreate = commodityRepository.findAll().size();

        // Create the Commodity with an existing ID
        commodity.setId(1L);
        CommodityDTO commodityDTO = commodityMapper.toDto(commodity);

        // An entity with an existing ID cannot be created, so this API call must fail
        restCommodityMockMvc.perform(post("/api/commodities")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(commodityDTO)))
            .andExpect(status().isBadRequest());

        // Validate the Commodity in the database
        List<Commodity> commodityList = commodityRepository.findAll();
        assertThat(commodityList).hasSize(databaseSizeBeforeCreate);
    }


    @Test
    @Transactional
    public void getAllCommodities() throws Exception {
        // Initialize the database
        commodityRepository.saveAndFlush(commodity);

        // Get all the commodityList
        restCommodityMockMvc.perform(get("/api/commodities?sort=id,desc"))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(jsonPath("$.[*].id").value(hasItem(commodity.getId().intValue())))
            .andExpect(jsonPath("$.[*].cname").value(hasItem(DEFAULT_CNAME.toString())))
            .andExpect(jsonPath("$.[*].star").value(hasItem(DEFAULT_STAR)))
            .andExpect(jsonPath("$.[*].price").value(hasItem(DEFAULT_PRICE.doubleValue())))
            .andExpect(jsonPath("$.[*].imgUrl").value(hasItem(DEFAULT_IMG_URL.toString())))
            .andExpect(jsonPath("$.[*].detail").value(hasItem(DEFAULT_DETAIL.toString())))
            .andExpect(jsonPath("$.[*].model").value(hasItem(DEFAULT_MODEL.toString())))
            .andExpect(jsonPath("$.[*].createTime").value(hasItem(sameInstant(DEFAULT_CREATE_TIME))))
            .andExpect(jsonPath("$.[*].count").value(hasItem(DEFAULT_COUNT)))
            .andExpect(jsonPath("$.[*].fashion").value(hasItem(DEFAULT_FASHION.toString())))
            .andExpect(jsonPath("$.[*].quality").value(hasItem(DEFAULT_QUALITY.toString())))
            .andExpect(jsonPath("$.[*].brand").value(hasItem(DEFAULT_BRAND.toString())));
    }
    
    @Test
    @Transactional
    public void getCommodity() throws Exception {
        // Initialize the database
        commodityRepository.saveAndFlush(commodity);

        // Get the commodity
        restCommodityMockMvc.perform(get("/api/commodities/{id}", commodity.getId()))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(jsonPath("$.id").value(commodity.getId().intValue()))
            .andExpect(jsonPath("$.cname").value(DEFAULT_CNAME.toString()))
            .andExpect(jsonPath("$.star").value(DEFAULT_STAR))
            .andExpect(jsonPath("$.price").value(DEFAULT_PRICE.doubleValue()))
            .andExpect(jsonPath("$.imgUrl").value(DEFAULT_IMG_URL.toString()))
            .andExpect(jsonPath("$.detail").value(DEFAULT_DETAIL.toString()))
            .andExpect(jsonPath("$.model").value(DEFAULT_MODEL.toString()))
            .andExpect(jsonPath("$.createTime").value(sameInstant(DEFAULT_CREATE_TIME)))
            .andExpect(jsonPath("$.count").value(DEFAULT_COUNT))
            .andExpect(jsonPath("$.fashion").value(DEFAULT_FASHION.toString()))
            .andExpect(jsonPath("$.quality").value(DEFAULT_QUALITY.toString()))
            .andExpect(jsonPath("$.brand").value(DEFAULT_BRAND.toString()));
    }

    @Test
    @Transactional
    public void getNonExistingCommodity() throws Exception {
        // Get the commodity
        restCommodityMockMvc.perform(get("/api/commodities/{id}", Long.MAX_VALUE))
            .andExpect(status().isNotFound());
    }

    @Test
    @Transactional
    public void updateCommodity() throws Exception {
        // Initialize the database
        commodityRepository.saveAndFlush(commodity);

        int databaseSizeBeforeUpdate = commodityRepository.findAll().size();

        // Update the commodity
        Commodity updatedCommodity = commodityRepository.findById(commodity.getId()).get();
        // Disconnect from session so that the updates on updatedCommodity are not directly saved in db
        em.detach(updatedCommodity);
        updatedCommodity
            .cname(UPDATED_CNAME)
            .star(UPDATED_STAR)
            .price(UPDATED_PRICE)
            .imgUrl(UPDATED_IMG_URL)
            .detail(UPDATED_DETAIL)
            .model(UPDATED_MODEL)
            .createTime(UPDATED_CREATE_TIME)
            .count(UPDATED_COUNT)
            .fashion(UPDATED_FASHION)
            .quality(UPDATED_QUALITY)
            .brand(UPDATED_BRAND);
        CommodityDTO commodityDTO = commodityMapper.toDto(updatedCommodity);

        restCommodityMockMvc.perform(put("/api/commodities")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(commodityDTO)))
            .andExpect(status().isOk());

        // Validate the Commodity in the database
        List<Commodity> commodityList = commodityRepository.findAll();
        assertThat(commodityList).hasSize(databaseSizeBeforeUpdate);
        Commodity testCommodity = commodityList.get(commodityList.size() - 1);
        assertThat(testCommodity.getCname()).isEqualTo(UPDATED_CNAME);
        assertThat(testCommodity.getStar()).isEqualTo(UPDATED_STAR);
        assertThat(testCommodity.getPrice()).isEqualTo(UPDATED_PRICE);
        assertThat(testCommodity.getImgUrl()).isEqualTo(UPDATED_IMG_URL);
        assertThat(testCommodity.getDetail()).isEqualTo(UPDATED_DETAIL);
        assertThat(testCommodity.getModel()).isEqualTo(UPDATED_MODEL);
        assertThat(testCommodity.getCreateTime()).isEqualTo(UPDATED_CREATE_TIME);
        assertThat(testCommodity.getCount()).isEqualTo(UPDATED_COUNT);
        assertThat(testCommodity.getFashion()).isEqualTo(UPDATED_FASHION);
        assertThat(testCommodity.getQuality()).isEqualTo(UPDATED_QUALITY);
        assertThat(testCommodity.getBrand()).isEqualTo(UPDATED_BRAND);
    }

    @Test
    @Transactional
    public void updateNonExistingCommodity() throws Exception {
        int databaseSizeBeforeUpdate = commodityRepository.findAll().size();

        // Create the Commodity
        CommodityDTO commodityDTO = commodityMapper.toDto(commodity);

        // If the entity doesn't have an ID, it will throw BadRequestAlertException
        restCommodityMockMvc.perform(put("/api/commodities")
            .contentType(TestUtil.APPLICATION_JSON_UTF8)
            .content(TestUtil.convertObjectToJsonBytes(commodityDTO)))
            .andExpect(status().isBadRequest());

        // Validate the Commodity in the database
        List<Commodity> commodityList = commodityRepository.findAll();
        assertThat(commodityList).hasSize(databaseSizeBeforeUpdate);
    }

    @Test
    @Transactional
    public void deleteCommodity() throws Exception {
        // Initialize the database
        commodityRepository.saveAndFlush(commodity);

        int databaseSizeBeforeDelete = commodityRepository.findAll().size();

        // Delete the commodity
        restCommodityMockMvc.perform(delete("/api/commodities/{id}", commodity.getId())
            .accept(TestUtil.APPLICATION_JSON_UTF8))
            .andExpect(status().isNoContent());

        // Validate the database contains one less item
        List<Commodity> commodityList = commodityRepository.findAll();
        assertThat(commodityList).hasSize(databaseSizeBeforeDelete - 1);
    }

    @Test
    @Transactional
    public void equalsVerifier() throws Exception {
        TestUtil.equalsVerifier(Commodity.class);
        Commodity commodity1 = new Commodity();
        commodity1.setId(1L);
        Commodity commodity2 = new Commodity();
        commodity2.setId(commodity1.getId());
        assertThat(commodity1).isEqualTo(commodity2);
        commodity2.setId(2L);
        assertThat(commodity1).isNotEqualTo(commodity2);
        commodity1.setId(null);
        assertThat(commodity1).isNotEqualTo(commodity2);
    }

    @Test
    @Transactional
    public void dtoEqualsVerifier() throws Exception {
        TestUtil.equalsVerifier(CommodityDTO.class);
        CommodityDTO commodityDTO1 = new CommodityDTO();
        commodityDTO1.setId(1L);
        CommodityDTO commodityDTO2 = new CommodityDTO();
        assertThat(commodityDTO1).isNotEqualTo(commodityDTO2);
        commodityDTO2.setId(commodityDTO1.getId());
        assertThat(commodityDTO1).isEqualTo(commodityDTO2);
        commodityDTO2.setId(2L);
        assertThat(commodityDTO1).isNotEqualTo(commodityDTO2);
        commodityDTO1.setId(null);
        assertThat(commodityDTO1).isNotEqualTo(commodityDTO2);
    }

    @Test
    @Transactional
    public void testEntityFromId() {
        assertThat(commodityMapper.fromId(42L).getId()).isEqualTo(42);
        assertThat(commodityMapper.fromId(null)).isNull();
    }
}
